package orderedmap

import (
	"fmt"
	"iptv_server/v3/v2_src/utils"
	"iptv_server/v3/v2_src/utils/common"
)

func New[T any]() *Orderedmap[T] {
	return &Orderedmap[T]{
		store:   make(map[string]T),
		ordered: make([]string, 0, 10),
	}
}

// 顺序=Set时的顺序, 只能存 不能删,
type Orderedmap[T any] struct {
	store   map[string]T
	ordered []string
}

func (o *Orderedmap[T]) Get(key string) (v T, ok bool) {
	v, ok = o.store[key]
	return
}

func (o *Orderedmap[T]) Set(key string, v T) {
	if _, ok := o.store[key]; !ok {
		o.ordered = append(o.ordered, key)
	}
	o.store[key] = v
}

func (o *Orderedmap[T]) Size() int {
	return len(o.ordered)
}

func (o *Orderedmap[T]) Keys() []string {
	return o.ordered

}

func (o *Orderedmap[T]) GetPair(index int) (k string, v T, ok bool) {
	if o.Size() > index && index >= 0 {
		k = o.ordered[index]
		v = o.store[k]
		ok = true
		return
	}
	return k, v, false
}

// func (o *Orderedmap[T]) ResortKeys(sorter []string, filter map[string]struct{}) {
func (o *Orderedmap[T]) ResortKeys(sorter common.Sorter, filter common.Filter) {

	if len(o.ordered) == 0 {
		return
	}

	sorter_is_empty := common.IsEmpty(sorter)
	filter_is_empty := common.IsEmpty(filter)

	if sorter_is_empty && filter_is_empty {
		utils.Logger.Debugf("filter sorter && filter is Empty \n")
		return
	}

	got := make(map[string]struct{})
	newkeys := make([]string, 0, 16)

	if !sorter_is_empty {
		utils.Logger.Debugf("sorter size: %v\n", sorter.Size())
		for i := 0; i < sorter.Size(); i++ {
			k := sorter.GetN(i)
			//  _, k := range sorter {
			if _, ok := o.Get(k); ok {
				if filter_is_empty || !filter.Contains(k) {
					newkeys = append(newkeys, k)
					// fmt.Printf("sorter key=%s \n", k)
					got[k] = struct{}{}

				}
			}
		}
	}

	if !filter_is_empty {
		utils.Logger.Debugf("filter.Keys(): %v\n", filter.Keys())
	}

	for _, k := range o.ordered {
		// fmt.Printf("filter key=%s \n", k)
		if !filter_is_empty && filter.Contains(k) {
			delete(o.store, k)
			fmt.Printf("filter delete key=%s \n", k)
			continue
		}
		if _, ok2 := got[k]; ok2 {
			continue
		}
		newkeys = append(newkeys, k)
	}
	o.ordered = newkeys
}

// func (o *Orderedmap[T]) Range() func(yield func(int, T) bool) {
// 	return func(yield func(int, T) bool) {
// 		for i := 0; i < o.Size(); i++ {
// 			if !yield(i, o.store[o.soter[i]]) {
// 				return
// 			}
// 		}
// 	}
// }
